from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from io import BytesIO
import pandas as pd
from django.http import HttpResponse
import logging

from ..models import Product
from ..serializers import ProductSerializer
from apps.UMM.models import CommissionCategory
from apps.UMM.permissions import IsAdminUserOrReadCreateOnly

logger = logging.getLogger(__name__)

class ProductViewSet(viewsets.ModelViewSet):
    """产品视图集"""
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    permission_classes = [IsAdminUserOrReadCreateOnly]
    
    def get_queryset(self):
        """实现查询过滤"""
        queryset = super().get_queryset()
        
        # 获取查询参数
        product_name = self.request.query_params.get('product_name', None)
        product_tag = self.request.query_params.get('product_tag', None)
        commission_category = self.request.query_params.get('commission_category', None)
        
        # 应用过滤条件
        if product_name:
            queryset = queryset.filter(product_name__icontains=product_name)
        if product_tag:
            queryset = queryset.filter(product_tag__icontains=product_tag)
        if commission_category:
            queryset = queryset.filter(commission_category=commission_category)
            
        return queryset
    
    @action(detail=False, methods=['post'])
    def batch_delete(self, request):
        """批量删除产品"""
        # 权限检查 - 只有管理员可以删除
        if not hasattr(request.user, 'role') or request.user.role != 1:
            return Response({"message": "您没有权限执行此操作，只有管理员可以删除产品"}, 
                           status=status.HTTP_403_FORBIDDEN)
                           
        ids = request.data.get('ids', [])
        if not ids:
            return Response({"message": "未提供要删除的产品ID"}, status=status.HTTP_400_BAD_REQUEST)
        
        Product.objects.filter(id__in=ids).delete()
        return Response({"message": "批量删除成功"}, status=status.HTTP_200_OK)
    
    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出产品数据为Excel"""
        queryset = self.get_queryset()
        
        # 创建一个空的DataFrame
        df = pd.DataFrame()
        
        # 添加所需列
        df['产品ID'] = [product.id for product in queryset]
        df['产品名称'] = [product.product_name for product in queryset]
        df['产品标签'] = [product.product_tag for product in queryset]
        df['提成分类'] = [product.commission_category.commission_category for product in queryset]
        df['提成比例'] = [product.commission_category.commission_ratio for product in queryset]
        
        # 创建一个字节流
        output = BytesIO()
        
        # 将DataFrame写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='产品数据', index=False)
            
        # 设置文件指针到开始
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=产品数据.xlsx'
        
        return response
        
    @action(detail=False, methods=['get'])
    def import_template(self, request):
        """下载产品导入模板"""
        # 创建一个空的DataFrame
        df = pd.DataFrame(columns=['产品名称*', '产品标签', '提成分类*'])
        
        # 添加示例数据行
        df.loc[0] = ['产品示例(必填且唯一)', '标签1,标签2,标签3', '标准提成']
        
        # 获取所有提成分类
        commission_categories = CommissionCategory.objects.all()
        category_names = [cat.commission_category for cat in commission_categories]
        
        # 添加说明行
        df.loc[1] = ['', '多个标签用英文逗号分隔', f'可选值: {", ".join(category_names)}']
        
        # 创建一个字节流
        output = BytesIO()
        
        # 将DataFrame写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='产品导入模板', index=False)
            
            # 获取工作簿和工作表
            workbook = writer.book
            worksheet = writer.sheets['产品导入模板']
            
            # 添加格式
            header_format = workbook.add_format({
                'bold': True,
                'bg_color': '#D9EAD3',
                'border': 1
            })
            
            # 设置列宽
            worksheet.set_column('A:A', 25)
            worksheet.set_column('B:B', 30)
            worksheet.set_column('C:C', 25)
            
            # 应用格式到表头
            for col_num, value in enumerate(df.columns.values):
                worksheet.write(0, col_num, value, header_format)
                
            # 添加说明
            notes_format = workbook.add_format({
                'italic': True,
                'font_color': '#808080'
            })
            
            # 在底部添加说明
            worksheet.write(4, 0, '注意事项:', workbook.add_format({'bold': True}))
            worksheet.write(5, 0, '1. 带*的字段为必填项', notes_format)
            worksheet.write(6, 0, '2. 产品名称必须唯一，系统会自动检查是否存在重复', notes_format)
            worksheet.write(7, 0, '3. 提成分类必须是系统中已存在的分类名称', notes_format)
            
        # 设置文件指针到开始
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=产品导入模板.xlsx'
        
        return response
        
    @action(detail=False, methods=['post'])
    def import_data(self, request):
        """导入产品数据"""
        file = request.FILES.get('file')
        if not file:
            return Response({'success': False, 'message': '请上传文件'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 检查文件类型
        if not file.name.endswith(('.xlsx', '.xls')):
            return Response({'success': False, 'message': '只支持Excel文件(.xlsx或.xls)'}, status=status.HTTP_400_BAD_REQUEST)
        
        try:
            # 读取Excel文件
            df = pd.read_excel(file)
            
            # 验证必要的列是否存在
            required_columns = ['产品名称*', '提成分类*']
            for column in required_columns:
                if column not in df.columns:
                    return Response({'success': False, 'message': f'导入文件缺少必要的列：{column}'}, status=status.HTTP_400_BAD_REQUEST)
            
            # 重命名列以匹配模型字段
            column_mapping = {
                '产品名称*': 'product_name',
                '产品标签': 'product_tag',
                '提成分类*': 'commission_category_name'
            }
            df = df.rename(columns=column_mapping)
            
            # 验证产品名称是否为空
            if df['product_name'].isnull().any():
                return Response({'success': False, 'message': '产品名称不能为空'}, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证产品名称是否有重复（在导入数据中）
            duplicate_names = df[df.duplicated('product_name', keep=False)]['product_name'].unique()
            if len(duplicate_names) > 0:
                duplicates_str = ', '.join(duplicate_names)
                return Response({
                    'success': False, 
                    'message': f'导入数据中存在重复的产品名称: {duplicates_str}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证产品名称是否与数据库中的产品重复
            existing_names = []
            for name in df['product_name']:
                if Product.objects.filter(product_name=name).exists():
                    existing_names.append(name)
            
            if existing_names:
                existing_str = ', '.join(existing_names)
                return Response({
                    'success': False, 
                    'message': f'以下产品名称已存在于数据库中: {existing_str}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证提成分类是否存在
            invalid_categories = []
            category_dict = {}  # 创建提成分类名称到ID的映射
            for category_name in df['commission_category_name'].unique():
                try:
                    category = CommissionCategory.objects.get(commission_category=category_name)
                    category_dict[category_name] = category.id
                except CommissionCategory.DoesNotExist:
                    invalid_categories.append(category_name)
            
            if invalid_categories:
                invalid_str = ', '.join(invalid_categories)
                return Response({
                    'success': False, 
                    'message': f'以下提成分类不存在于系统中: {invalid_str}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 开始导入数据
            imported_count = 0
            for _, row in df.iterrows():
                data = {
                    'product_name': row['product_name'],
                    'commission_category': category_dict[row['commission_category_name']]
                }
                
                # 如果产品标签列存在且不为空
                if 'product_tag' in row and pd.notna(row['product_tag']):
                    data['product_tag'] = str(row['product_tag'])
                
                # 创建产品记录
                serializer = self.get_serializer(data=data)
                serializer.is_valid(raise_exception=True)
                serializer.save()
                imported_count += 1
                
            return Response({
                'success': True,
                'message': f'成功导入{imported_count}条产品记录',
                'imported_count': imported_count
            })
        
        except Exception as e:
            logger.error(f"导入产品数据失败: {str(e)}")
            return Response({'success': False, 'message': f'导入失败: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=False, methods=['get'])
    def server_rental(self, request):
        """获取主机出租类型的产品"""
        try:
            # 简化查询逻辑，直接查找产品名称包含"主机出租"的产品
            server_rental_products = Product.objects.filter(
                product_name__icontains='主机出租'
            )
            
            # 如果没有找到产品，返回空列表但不报错
            serializer = self.get_serializer(server_rental_products, many=True)
            return Response(serializer.data)
        except Exception as e:
            logger.error(f"获取主机出租产品失败: {str(e)}")
            return Response({"message": f"获取主机出租产品失败: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 